using System;
using System.Collections.Generic;

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using SlamCms.Common.Internal;

namespace SlamCms.Common
{
	public static class ImageResizer
	{
		public static Stream CropResizeImageFromStream(Stream fileStream, int maxImageWidth, int maxImageHeight)
		{
			return CropResizeImageFromStream(fileStream, maxImageWidth, maxImageHeight, 100L, false);
		}

		public static Stream CropResizeImageFromStream(Stream fileStream, int maxImageWidth, int maxImageHeight, long jpegQuality, bool alwaysProcess)
		{
			MemoryStream outputFile = new MemoryStream();
			using (Image image = Image.FromStream(fileStream))
			{	
				using (Image resizedImage = image.ResizeFit(maxImageWidth, maxImageHeight, !alwaysProcess))
				{
					using(Image croppedImage = resizedImage.CropByAspectRatio(maxImageWidth, maxImageHeight))
					{
						if (image.RawFormat.Guid == ImageFormat.Jpeg.Guid)
						{
							croppedImage.SaveJpeg(outputFile, jpegQuality);
						}
						else if (image.RawFormat.Guid == ImageFormat.Gif.Guid)
						{
							croppedImage.SaveGif(outputFile, image.Palette.Entries.Length > 255 ? 255 : image.Palette.Entries.Length);
						}
						else
						{
							croppedImage.Save(outputFile, image.RawFormat);
						}
					}
				}
			}
			return outputFile;
		}

		public static Stream ResizeImageFromStream(Stream fileStream, int maxImageWidth, int maxImageHeight)
		{
			return ResizeImageFromStream(fileStream, maxImageWidth, maxImageHeight, 100L, false);
		}

		public static Stream ResizeImageFromStream(Stream fileStream, int maxImageWidth, int maxImageHeight, long jpegQuality, bool alwaysProcess)
		{
			MemoryStream outputFile = new MemoryStream();
			using (Image image = Image.FromStream(fileStream))
			{	
				using (Image resizedImage = image.Resize(maxImageWidth, maxImageHeight, !alwaysProcess))
				{
					if (image.RawFormat.Guid == ImageFormat.Jpeg.Guid)
					{
						resizedImage.SaveJpeg(outputFile, jpegQuality);
					}
					else if (image.RawFormat.Guid == ImageFormat.Gif.Guid)
					{
						resizedImage.SaveGif(outputFile, image.Palette.Entries.Length > 255 ? 255 : image.Palette.Entries.Length);
					}
					else
					{
						resizedImage.Save(outputFile, image.RawFormat);
					}
				}
			}
			return outputFile;
		}

		public static void ResizeAndSaveImage(string imagePath, string resizedImagePath, int maxImageWidth, int maxImageHeight, bool overwrite)
		{
			ResizeAndSaveImage(imagePath, resizedImagePath, maxImageWidth, maxImageHeight, 100L, false, overwrite);
		}

		public static void ResizeAndSaveImage(string imagePath, string resizedImagePath, int maxImageWidth, int maxImageHeight, long jpegQuality, bool alwaysProcess, bool overwrite)
		{
			string newImagePath = resizedImagePath;
			if (imagePath.ToLower().EndsWith(".eps") || imagePath.ToLower().EndsWith(".ps") || imagePath.ToLower().EndsWith(".pdf"))
			{
				PostScriptImageExtracter.SaveImage(imagePath, 1, newImagePath);
				imagePath = newImagePath;
			}

			using (Image image = Image.FromFile(imagePath))
			{
				using (Image resizedImage = image.Resize(maxImageWidth, maxImageHeight, !alwaysProcess))
				{
					//save as [filename]_temp
					if (resizedImagePath.Equals(imagePath, StringComparison.OrdinalIgnoreCase))
					{
						newImagePath = resizedImagePath + "_temp";
					}

					if (resizedImage.Width < image.Width || resizedImage.Height < image.Height)
					{
						if (image.RawFormat.Guid == ImageFormat.Jpeg.Guid)
						{
							resizedImage.SaveJpeg(newImagePath, jpegQuality);
						}
						else if (image.RawFormat.Guid == ImageFormat.Gif.Guid)
						{
							resizedImage.SaveGif(newImagePath, image.Palette.Entries.Length > 255 ? 255 : image.Palette.Entries.Length);
						}
						else
						{
							resizedImage.Save(newImagePath, image.RawFormat);
						}
					}
					else
					{
						File.Copy(imagePath, newImagePath, overwrite);
					}
				}
			}

			//delete original file and keep the resized version 
			//as its replacement
			if (resizedImagePath.Equals(imagePath, StringComparison.OrdinalIgnoreCase))
			{
				File.Delete(imagePath);
				File.Move(newImagePath, newImagePath.Substring(0, newImagePath.Length - 5));
			}
		}
	}
}
